home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / game / role / ldmud-3.2-bin.lha / mud / doc / concepts / erq < prev    next >
Text File  |  2001-04-06  |  23KB  |  543 lines

  1. CONCEPT
  2.         erq - External Request Demon
  3.  
  4. DESCRIPTION
  5.         Up to version 3.2.1@61, LPMud utilized two external programs
  6.         in an ad-hoc manner to solve problems: the 'hname' program to
  7.         resolve IP addresses into meaningful hostnames, and the
  8.         'indent' program to properly indent LPC files.
  9.         In version 3.2.1@61 both functions were united in a
  10.         generalized 'erq' process, to which additional functions may
  11.         be attached. Unfortunately it was never documented by Amylaar,
  12.         so the information presented here had to be reverse engineered
  13.         from the sources - better take it with a grain of salt.
  14.  
  15.         The erq feature is available if the driver is compiled with
  16.         ERQ_DEMON defined (in config.h).
  17.  
  18.         When the driver starts up, it tries to fork off the program
  19.         'BINDIR/erq --forked' (with BINDIR defined in the Makefile).
  20.         If this succeeds, the erq may talk with the driver through
  21.         stdin and stdout (piped through AF_UNIX sockets). The erq has
  22.         to signal its successfull start by writing the character '1'
  23.         back to the driver.
  24.  
  25.         At runtime, the erq may be changed/removed from within the
  26.         mudlib using the efun attach_erq_demon(). This efun is given
  27.         an interactive object as argument, and takes the connection
  28.         away(!) from this object and stores it as the erq connection
  29.         to use (an old erq connection is closed first). The object
  30.         (which now no longer is interactive) is then no longer needed,
  31.         but may continue to exist.
  32.         The erq attached this way of course has to use the sockets it
  33.         opened to communicate with the driver.
  34.  
  35.         Most of the communication between erq and driver is going to
  36.         be initiated by the driver (the erq has to look up the
  37.         hostnames for given IP addresses), but using the efun
  38.         send_erq() the mudlib may talk with the erq as well.
  39.  
  40.         The communication between driver and erq is done using
  41.         messages of specified structures and constants (defined in
  42.         util/erq.h resp. sys/erq.h). The 'int32's are signed integers
  43.         of four byte length, and are sent with the MSByte first.
  44.         Every message must be sent atomically!
  45.  
  46.         The head of the messages is always the same:
  47.  
  48.           struct erq_msghead {
  49.             int32  msglen;  /* Total size of message in bytes */
  50.             int32  handle;  /* Identification number */
  51.           }
  52.  
  53.         The 'handle' number is set by the driver (do not make
  54.         assumptions about its value) and is used to associated the erq
  55.         responses with the pending requests. This way the erq is free
  56.         to respond in an order different to those of the incoming
  57.         requests.
  58.  
  59.         The messages send to the erq follow this symbolic format:
  60.  
  61.           struct to_erq_msg {
  62.             int32  msglen;
  63.             int32  handle;
  64.             char   request;
  65.             char   data[0];
  66.           }
  67.  
  68.         The 'request' denotes which service is requested from the erq,
  69.         the size and content of 'data' depends on the requested
  70.         service.
  71.  
  72.         The answer message from the erq to the driver (if there is one
  73.         at all) may have two forms:
  74.  
  75.           struct from_erq_msg {
  76.             int32  msglen;
  77.             int32  handle;
  78.             char   data[0];
  79.           }
  80.  
  81.           struct from_erq_keep_msg {
  82.             int32        msglen;
  83.             const int32  keep = ERQ_KEEP_HANDLE;
  84.             int32        handle;
  85.             char         data[0];
  86.           }
  87.  
  88.         The replied data from the erq is stored in 'data', which size
  89.         and content depends on the request answered. The answer is
  90.         identified by 'header.handle'. Normally, one request results
  91.         in just one response sent by the erq using struct from_erq_msg,
  92.         so the handle is recycled after this response.
  93.         Shall the erq send several responses (or break one response
  94.         into several parts), the struct from_erq_keep_msg has to be
  95.         used for all but the last response - this message with its
  96.         included special handle keeps the real handle alive.
  97.  
  98.         
  99.         Mudlib generated erq-calls specify the 'request' and the
  100.         'data' to be sent, and receive the 'data' replied. When
  101.         dealing with spawned programs, the first byte of the returned
  102.         'data' determines the content type of the received message.
  103.         The actual 'data' which the lpc programs get to see is sent
  104.         and retrieved as arrays of byte integers (integers in the
  105.         range of 0..255).
  106.  
  107.  
  108.         The actual interface between erq demon and driver is limited
  109.         to the general message formats and the hostname lookup
  110.         mechanism. The driver is meant to withstand erq demon failures
  111.         at least in a garbage-in garbage-out fashion. You could add
  112.         new requests to the erq demon, or write your own from scratch,
  113.         without changing the driver.
  114.  
  115.  
  116.         Currently five services are predefined in the supplied
  117.         erq-demon (util/erq.c in the driver source archive): looking
  118.         up a hostname, execution, forking or spawning an external
  119.         program, authentification of a connection, and handling of
  120.         external UDP/TCP connections. As mentioned above, only the
  121.         hostname-lookup is a true must.
  122.  
  123.         For a program to be executable for erq, it must be placed in
  124.         or below ERQ_DIR (defined in config.h). On most unix systems,
  125.         it is possible to use a symlink instead of the whole program
  126.         if you want a standard binary. You could even symlink entire
  127.         directories like /usr/sbin, but chances are you make a big
  128.         security hole this way :-)
  129.  
  130.  
  131.         Hostname lookup:
  132.  
  133.           request  : ERQ_RLOOKUP
  134.           data sent: struct in_addr.s_addr addr // the address to resolve
  135.           data recv: struct in_addr.s_addr addr // the resolved address
  136.                      char[]                name // the hostname (if any)
  137.  
  138.           If the sent address can't be resolved, just the address is
  139.           to be returned. The string need not be 0-terminated.
  140.  
  141.  
  142.         Hostname lookup:
  143.  
  144.           request  : ERQ_LOOKUP
  145.           data sent: char[]                name // the name to resolve
  146.           data recv: struct in_addr.s_addr addr // the resolved address
  147.  
  148.           If the sent address can't be resolved, no data is returned (the
  149.           driver will get a message with just the header).
  150.  
  151.  
  152.         Hostname lookup - IPv6:
  153.  
  154.           request  : ERQ_RLOOKUPV6
  155.           data sent: char[] addr  // the address to resolve
  156.           data recv: char[] data  // the resolved name
  157.  
  158.           If the address could be resolved, the returned data is a string,
  159.           with exactly one space, in the form "<addr> <name>". <addr> is
  160.           the address passed to the erq, <name> is the hostname of the
  161.           address or, if there is no reverse-IPv6 entry for <addr>, the
  162.           IPv6 address which may or may not be different from <addr>.
  163.  
  164.           If the address can not be resolved, the returned data is
  165.           an error message without a space (currently, just "invalid-format"
  166.           and "out-of-memory" are returned).
  167.  
  168.  
  169.         Execute/Fork program:
  170.  
  171.           request  : ERQ_EXECUTE/ERQ_FORK
  172.           data sent: char[] command  // the command to execute
  173.           data recv: char   status = CHILD_FREE
  174.                      char   rc       // the success/error code
  175.                      char   info     // additional information
  176.  
  177.           The erq executes the sent command using the execv().
  178.           The erq does the processing of the command line arguments
  179.           (which must not contain '\') and checks the validity of the
  180.           command (it must not start with '/' nor contain '..'), which
  181.           is interpreted relative to ERQ_DIR.
  182.           The external program is executed from a fork()ed instance of
  183.           the erq, however, with ERQ_EXECUTE the erq waits until the
  184.           external program finished before replying its response, with
  185.           ERQ_FORK the response is immediately sent back.
  186.  
  187.           Possible return codes are:
  188.             ERQ_OK         : Operation succeeded.
  189.             ERQ_E_ARGLENGTH: Too long command.
  190.             ERQ_E_ARGFORMAT: Illegal argument given (contains '\');
  191.             ERQ_E_ARGNUMBER: Too much arguments (>= 96).
  192.             ERQ_E_ILLEGAL  : Command from outside ERQ_DIR requested.
  193.             ERQ_E_PATHLEN  : Commandpath too long.
  194.             ERQ_E_FORKFAIL : Command could not be forked;
  195.                              info holds the errno value.
  196.  
  197.           ERQ_EXECUTE features some more return codes:
  198.             ERQ_OK         : Operation succeeded, <info> holds the exit status.
  199.             ERQ_SIGNALED   : Command terminated the signal <info>.
  200.             ERQ_E_NOTFOUND : No process found to wait() for.
  201.             ERQ_E_UNKNOWN  : Unknown exit condition from wait().
  202.  
  203.  
  204.         Spawn program:
  205.  
  206.           request  : ERQ_SPAWN
  207.           data sent: char[] command  // the command to execute
  208.           data recv: Spawn failed:
  209.                      char   rc       // the error code (see ERQ_FORK)
  210.                      char   info     // additional information
  211.           data recv: Spawn succeeded:
  212.                      char   rc = ERQ_OK
  213.                      char[] ticket        // the spawn ticket.
  214.  
  215.           The erq executes the sent command as if given an ERQ_FORK
  216.           command, but returns additional information about the
  217.           started process to allow further communication.
  218.           In contrast to ERQ_FORK, ERQ_SPAWNED processes may be
  219.           controlled via ERQ_KILL, receive data from the mud via
  220.           ERQ_SEND on their stdin, and output from their stdout/stderr
  221.           is sent back to the mud.
  222.           The spawned process is identified by its <ticket> (don't
  223.           make any assumptions about its length or content), the transaction
  224.           itself by <handle>.
  225.  
  226.  
  227.         Send data to spawned program:
  228.  
  229.           request  : ERQ_SEND
  230.           data sent: char[]  ticket // the addressed process ticket.
  231.                      char[]  text   // the text to send.
  232.           data recv: char    rc     // the success/error code.
  233.                      int32   info   // opt: additional info.
  234.  
  235.           The <text> is sent to the stdin of the spawned process
  236.           identified by <ticket>.
  237.  
  238.           Possible return codes are:
  239.             ERQ_OK          : Operation succeeded, no <info> is replied.
  240.             ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
  241.             ERQ_E_INCOMPLETE: Only <info> chars of the text have been
  242.                               sent.
  243.             ERQ_E_WOULDBLOCK: Error E_WOULDBLOCK (also stored in <info>)
  244.                               happened while sending the text.
  245.             ERQ_E_PIPE      : Error E_PIPE (also stored in <info>)
  246.                               happened while sending the text.
  247.             ERQ_E_UNKNOWN   : The error with code <info> happened
  248.                               while sending the data.
  249.  
  250.  
  251.         Send a signal to a spawned program:
  252.  
  253.           request  : ERQ_KILL
  254.           data sent: char[]  ticket // the addressed process ticket
  255.                      int32   signal // the signal to send
  256.           data recv: char    rc     // the success/error code
  257.  
  258.           The <signal> is sent to the spawned process identified by <ticket>.
  259.  
  260.           Possible return codes are:
  261.             ERQ_OK          : Operation succeeded, no <info> is replied.
  262.             ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
  263.             ERQ_E_ILLEGAL   : The given signal is illegal.
  264.         
  265.  
  266.         Data replies from spawned programs:
  267.  
  268.           data recv: char   out_or_err  // type of text output
  269.                      char[] text        // text output by child process
  270.  
  271.           The child process controlled by the erq did output <text>
  272.           on stdout (<out_or_err> == ERQ_STDOUT) resp. on stderr
  273.           (<out_or_err> == ERQ_STDERR).
  274.  
  275.  
  276.         Exit notifications from spawned programs:
  277.  
  278.           data recv: char   rc          // the exit code
  279.                      char   info        // additional information.
  280.  
  281.           The child process controlled by the erq did terminate.
  282.           Possible exit codes are:
  283.             ERQ_EXITED    : Process exited with status <info>.
  284.             ERQ_SIGNALED  : Process terminated by signal <info>.
  285.             ERQ_E_UNKNOWN : Process terminated for unknown reason.
  286.  
  287.  
  288.         Authentificate connection (see rfc 931):
  289.  
  290.           request  : ERQ_AUTH
  291.           data sent: struct sockaddr_in remote // the address to check
  292.                      int32              port   // the mud port
  293.              or
  294.           data sent: int32  remote_ip    // remote ip to check
  295.                      int16  remote_port  // remote port to check
  296.                      int16  local_port   // the mud port
  297.  
  298.           data recv: char[]             reply  // the data received by authd
  299.  
  300.           The erq attempts to connect the authd on the remote system
  301.           and to verify the connection between the remote port and the
  302.           mud port. The latter will normally be the port number of the
  303.           socket on besides of the gamedriver, retrieveable by
  304.           query_ip_number().
  305.  
  306.           The answer from the authd (one line of text) if there is any
  307.           is returned as result.
  308.  
  309.           The second form of the ERQ_AUTH command is recognized by
  310.           the xerq as alternative.
  311.  
  312.  
  313.         Open an UPD port:
  314.  
  315.           request  : ERQ_OPEN_UDP
  316.           data sent: char[2] port   // the port number to open (network order)
  317.           data recv: Open failed:
  318.                      char    rc     // the success/error code.
  319.                      char    info   // opt: additional info.
  320.           data recv: Open succeeded:
  321.                      char   rc = ERQ_OK
  322.                      char[] ticket  // the connection ticket.
  323.  
  324.           The erq opens an UDP-port on the host machine with the given
  325.           port number.
  326.           Possible exit codes are:
  327.             ERQ_OK          : Operation succeeded.
  328.             ERQ_E_ARGLENGTH : The port number given does not consist
  329.                               of two bytes.
  330.             ERQ_E_NSLOTS    : The max number of child processes (given
  331.                               in <info>) is exhausted.
  332.             ERQ_E_UNKNOWN   : Error <info> occured in one of the system
  333.                               calls done to open the port.
  334.  
  335.           Once the port is open, it is treated as if is just another
  336.           spawned program.
  337.  
  338.  
  339.         Send data over an UDP port:
  340.  
  341.           request  : ERQ_SEND
  342.           data sent: char[]                ticket // the addressed port's ticket.
  343.                      struct in_addr.s_addr addr   // address of receiver.
  344.                      struct addr.sin_port  port   // port of receiver.
  345.                      char[]                text   // the text to send.
  346.           data recv: char   rc     // the success/error code.
  347.                      int32  info   // opt: additional info.
  348.  
  349.           The <text> is sent from our port <ticket> to the network
  350.           address <addr>, port <port>.
  351.  
  352.           Possible return codes are:
  353.             ERQ_OK          : Operation succeeded, no <info> is replied.
  354.             ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
  355.             ERQ_E_INCOMPLETE: Only <info> chars of the text have been
  356.                               sent.
  357.             ERQ_E_WOULDBLOCK: Error E_WOULDBLOCK (also stored in <info>)
  358.                               happened while sending the text.
  359.             ERQ_E_PIPE      : Error E_PIPE (also stored in <info>)
  360.                               happened while sending the text.
  361.             ERQ_E_UNKNOWN   : The error with code <info> happened
  362.                               while sending the data.
  363.  
  364.  
  365.         Close an UDP port:
  366.  
  367.           request  : ERQ_KILL
  368.           data sent: char[]  ticket // the addressed port's ticket
  369.                      int32   signal // the signal to send (ignored)
  370.           data recv: char    rc = ERQ_OK
  371.  
  372.           The port <ticket> is closed. The <signal> must be sent, but
  373.           its value is ignored.
  374.  
  375.  
  376.         Data received over an UDP connection:
  377.  
  378.           data recv: char                  out_or_err = ERQ_STDOUT
  379.                      struct in_addr.s_addr addr    // ip-address of sender
  380.                      struct addr.sin_port  port    // port of sender
  381.                      char[]                text    // data received
  382.  
  383.           The UPD port controlled by the erq did receive <text> over
  384.           the network from the sender at <addr>, reply port number <port>.
  385.  
  386.  
  387.         Open an TCP to listen for connections:
  388.  
  389.           request  : ERQ_LISTEN
  390.           data sent: struct addr.sin_port port   // the port number to open
  391.           data recv: Open failed:
  392.                      char    rc     // the success/error code.
  393.                      char    info   // opt: additional info.
  394.           data recv: Open succeeded:
  395.                      char   rc = ERQ_OK
  396.                      char[] ticket  // the connection ticket.
  397.  
  398.           The erq opens an TCP-port on the host machine with the given
  399.           port number to listen for connections.
  400.           Possible exit codes are:
  401.             ERQ_OK          : Operation succeeded.
  402.             ERQ_E_ARGLENGTH : The port number given does not consist
  403.                               of two bytes.
  404.             ERQ_E_NSLOTS    : The max number of child processes (given
  405.                               in <info>) is exhausted.
  406.             ERQ_E_UNKNOWN   : Error <info> occured in one of the system
  407.                               calls done to open the port.
  408.  
  409.           Once the port is open, it is treated as if is just another
  410.           spawned program.
  411.  
  412.  
  413.         Open an TCP port:
  414.  
  415.           request  : ERQ_OPEN_TCP
  416.           data sent: struct in_addr.s_addr ip   // the ip to address
  417.                      struct addr.sin_port  port // the port to address
  418.           data recv: Open failed:
  419.                      char    rc     // the success/error code.
  420.                      char    info   // opt: additional info.
  421.           data recv: Open succeeded:
  422.                      char   rc = ERQ_OK
  423.                      char[] ticket  // the connection ticket.
  424.  
  425.           The erq opens an TCP-port on the host machine and tries to connect
  426.           it to the address <ip>:<port>.
  427.           Possible exit codes are:
  428.             ERQ_OK          : Operation succeeded.
  429.             ERQ_E_ARGLENGTH : The port number given does not consist
  430.                               of two bytes.
  431.             ERQ_E_NSLOTS    : The max number of child processes (given
  432.                               in <info>) is exhausted.
  433.             ERQ_E_UNKNOWN   : Error <info> occured in one of the system
  434.                               calls done to open the port.
  435.  
  436.           Once the port is open, it is treated as if is just another
  437.           spawned program.
  438.  
  439.  
  440.         Send data over a TCP connection:
  441.  
  442.           request  : ERQ_SEND
  443.           data sent: char[]  ticket // the addressed process ticket.
  444.                      char[]  text   // the text to send.
  445.           data recv: char    rc     // the success/error code.
  446.                      int32   info   // opt: additional info.
  447.  
  448.           The <text> is sent to the stdin of the spawned process
  449.           identified by <ticket>.
  450.  
  451.           Possible return codes are:
  452.             ERQ_OK          : Operation succeeded, no <info> is replied.
  453.             ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
  454.             ERQ_E_INCOMPLETE: Only <info> chars of the text have been
  455.                               sent.
  456.             ERQ_E_WOULDBLOCK: Error E_WOULDBLOCK (also stored in <info>)
  457.                               happened while sending the text.
  458.             ERQ_E_PIPE      : Error E_PIPE (also stored in <info>)
  459.                               happened while sending the text.
  460.             ERQ_E_UNKNOWN   : The error with code <info> happened
  461.                               while sending the data.
  462.  
  463.  
  464.         Data ready to read on TCP connection:
  465.  
  466.           data recv: char    out_or_err = ERQ_OK
  467.                      char[]  ticket  // ticket of this connection
  468.  
  469.           There is data available to read on the specified TCP connection.
  470.  
  471.  
  472.         Data received over a TCP connection:
  473.  
  474.           data recv: char    out_or_err = ERQ_STDOUT
  475.                      char[]  text    // data received
  476.  
  477.           The TCP port controlled by the erq did receive <text>.
  478.  
  479.  
  480.         TCP connection closes on error:
  481.  
  482.           data recv: char    out_or_err = ERQ_E_UNKNOWN
  483.                      char    errno   // errno from socket operation
  484.  
  485.           The TCP connection caused an error <errno> and has been closed.
  486.  
  487.  
  488.         TCP connection closed:
  489.  
  490.           data recv: char    out_or_err = ERQ_EXITED
  491.  
  492.           The TCP connection closed regularily (End Of File).
  493.  
  494.  
  495.         Connection pending on TCP socket:
  496.  
  497.           data recv: char    out_or_err = ERQ_STDOUT
  498.  
  499.           The TCP 'listen' port controlled by the erq received
  500.           a connection request.
  501.  
  502.  
  503.         Accept a pending connections:
  504.  
  505.           request  : ERQ_ACCEPT
  506.           data sent: char[]  ticket // the ticket of this socket
  507.           data recv: Accept failed:
  508.                      char    rc     // the success/error code.
  509.                      char    info   // opt: additional info.
  510.           data recv: Accept succeeded:
  511.                      char    rc = ERQ_OK
  512.                      struct in_addr.s_addr ip    // remote side's ip
  513.                      struct addr.sin_port  port  // remote side's port
  514.                      char[]                ticket  // the new ticket.
  515.  
  516.           The erq accepts a new connection on an accept-TCP-port, creates
  517.           an child and ticket for it and returns it's ticket together with
  518.           the remote's side <ip>:<port> number (in network byte order).
  519.           Possible exit codes are:
  520.             ERQ_OK          : Operation succeeded.
  521.             ERQ_E_ARGLENGTH : The port number given does not consist
  522.                               of two bytes.
  523.             ERQ_E_NSLOTS    : The max number of child processes (given
  524.                               in <info>) is exhausted.
  525.             ERQ_E_TICKET    : the ticket didn't match
  526.             ERQ_E_UNKNOWN   : Error <info> occured in one of the system
  527.                               calls done to open the port.
  528.  
  529.           Once the port is open, it is treated as if is just another
  530.           spawned program.
  531.  
  532.  
  533. HISTORY
  534.         The erq was introduced with 3.2.1@61.
  535.         ERQ_AUTH was introduced with 3.2.1@81.
  536.         ERQ_SEND, ERQ_SPAWN, ERQ_KILL were introduced with 3.2.1@82.
  537.         ERQ_OPEN_UDP, ERQ_OPEN_TCP, ERQ_LIST were introduced with 3.2.1@98.
  538.         ERQ_RLOOKUPV6 was introduced in 3.2.8.
  539.  
  540. SEE ALSO
  541.         attach_erq_demon(E), send_erq(E), stale_erq(M), rfc 931
  542.         query_ip_number(E)
  543.